package bma.common.thrift;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TProtocol;

import bma.common.thrift.servicehub.ThriftServiceBean;
import bma.common.thrift.servicehub.ThriftServiceNode;

public class TProcessorModule extends TProcessorDispatchAbstract implements
		TProcessorDispatch {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(TProcessorModule.class);

	private String defaultModule;
	private Map<String, TProcessor> processors;

	public TProcessorModule() {
		super();
	}

	public TProcessorModule(Map<String, TProcessor> processors) {
		super();
		setProcessors(processors);
	}

	public Map<String, TProcessor> getProcessors() {
		return processors;
	}

	public void setProcessors(Map<String, TProcessor> processors) {
		this.processors = processors;
	}

	public void setServiceNode(ThriftServiceNode node) {
		setProcessorBeans(node.getServices());
	}

	public void setProcessorBeans(List<ThriftServiceBean> beans) {
		Map<String, TProcessor> m = new HashMap<String, TProcessor>();
		for (ThriftServiceBean bean : beans) {
			m.put(bean.getModule(), bean.getProcessor());
		}
		setProcessors(m);
	}

	public String getDefaultModule() {
		return defaultModule;
	}

	public void setDefaultModule(String defaultModule) {
		this.defaultModule = defaultModule;
	}

	@Override
	public TProcessor dispatch(TMessage msg, TProtocol in, TProtocol out)
			throws TException {
		TMessage newMsg = null;
		String module = null;
		String name = msg.name;
		int idx = name.indexOf('.');
		if (idx != -1) {
			module = name.substring(0, idx);
			name = name.substring(idx + 1);
			newMsg = new TMessage(name, msg.type, msg.seqid);
		}
		if (module == null && defaultModule != null) {
			module = defaultModule;
			newMsg = msg;
		}
		if (module == null) {
			throw new TApplicationException("'" + name + "' miss module");
		}
		if (log.isDebugEnabled()) {
			log.debug("processor({}) => {}", msg.name, module);
		}
		TProtocolCacheMessage inw = wrapIn(in);
		inw.setLastMessage(newMsg);
		TProcessor p = this.processors.get(module);
		if (p == null) {
			throw new TApplicationException("module '" + module
					+ "' miss processor");
		}
		return p;
	}

}
